<template>
  <div class="factory-content" v-loading="loading">
    <el-row :gutter="20">
      <el-col :span="6" align="left">
        <div class="factory-top">
          <icon-svg name="iconCalculate"></icon-svg>
          运算画布
        </div>
      </el-col>
      <el-col :span="18" align="right">
        <div class="btns">
          <el-button @click="handleReject">
            <icon-svg name="iconCancel"></icon-svg>
            取消
          </el-button>
          <el-button type="primary" @click="handlePreview" v-if="!preview">
            <icon-svg name="iconFacEye"></icon-svg>
            预览
          </el-button>
          <el-button type="primary" @click="preview = false" v-if="preview">
            <icon-svg name="iconReturn"></icon-svg>
            返回
          </el-button>
          <el-button type="primary" @click="handleSave">
            <icon-svg name="iconSave"></icon-svg>
            保存
          </el-button>
        </div>
      </el-col>
    </el-row>
    <div class="calculate-content tag-scrollbar" :class="{ borderd: !preview }">
      <calculate-preview
        ref="calculatePreview"
        :dataLabs="editForm.dataLabs"
        :results="editForm.results"
        v-if="preview"
      ></calculate-preview>
      <template v-else>
        <div class="calculate-preview">
          <h4>公式预览</h4>
          <calculate-logic :dataLabs="editForm.dataLabs"></calculate-logic>
        </div>
        <div class="calculate-logical">
          <ul class="clearfix">
            <li
              v-for="item in logicalList"
              :key="item.funcId"
              @click="addItem(Object.assign({}, item, { type_id: '0' }))"
            >
              {{ item.showOperator }}
            </li>
            <li @click="handleDelete"><icon-svg name="iconDelete"></icon-svg></li>
          </ul>
        </div>
        <div class="calculate-canvas" @drop="copyDrop($event)" @dragover="allowDrag($event)">
          <el-form :model="editForm" ref="editForm" label-width="0" v-if="this.editForm.dataLabs.length">
            <ul>
              <li
                v-for="(item, index) in editForm.dataLabs"
                :key="index"
                class="data-item"
                :index="index"
                :class="{ 'logic-item': item.type_id == '0' }"
              >
                <calculate-content-item
                  v-if="item.type_id == '2'"
                  :config="item"
                  :parentIndex="index"
                  :formProp="'dataLabs.' + index"
                  @dragstart="copyDrag($event, item, index)"
                ></calculate-content-item>
                <div class="item-content" draggable @dragstart="copyDrag($event, item, index)" v-else>
                  {{ item.type_id == '1' ? item.tag_nm : item.showOperator || item.symbol }}
                </div>
              </li>
            </ul>
          </el-form>
          <div class="config-tips" v-else>
            <span>
              <i class="el-icon-plus"></i>
            </span>
            <br />
            将标签或公式拖入此区域
          </div>
          <div class="canvas-handler delete-area">
            <icon-svg name="iconDelete" class="delete-area"></icon-svg><br />拖至此处删除
          </div>
        </div>
      </template>
    </div>
    <calculate-drawer ref="calculateDrawer" @callback="confirm"></calculate-drawer>
  </div>
</template>

<script>
import calculatePreview from './calculate-preview'
import calculateLogic from './calculate-logic'
import calculateContentItem from './calculate-content-item'
import calculateDrawer from './calculate-drawer'
import cloneDeep from 'lodash/cloneDeep'
export default {
  props: {
    logicalList: {
      type: Array,
      require: true,
      default: () => []
    }
  },
  components: {
    calculatePreview,
    calculateLogic,
    calculateContentItem,
    calculateDrawer
  },
  data() {
    return {
      loading: false,
      preview: false,
      previewLabs: [],
      oldConfig: {},
      editForm: {
        groupId: '',
        tagId: '',
        tagNm: '',
        fieldNm: '',
        execFrequency: '',
        execTm: '',
        execWkList: [],
        execDtList: [],
        tagStory: '',
        valueType: '',
        rerun: false,
        rerunTime: 1,
        dataLabs: [],
        results: []
      }
    }
  },
  methods: {
    getDetail(tagId) {
      this.editForm.tagId = tagId
      this.$ajax({
        url: this.$ajax.setUrl(`der/derTagCalculation/selectEditTag/${tagId}`),
        method: 'get',
        params: this.$ajax.setParams()
      }).then(({ data }) => {
        if (data && data.code === '0') {
          this.oldConfig = cloneDeep(data.data)
          this.previewLabs = cloneDeep(data.data.tagConfigJson)
          this.editForm.tagNm = data.data.tagNm
          this.editForm.fieldNm = data.data.fieldNm
          this.editForm.execFrequency = data.data.updateFrequency
          this.editForm.execTm = data.data.execTm
          this.editForm.execWkList = data.data.execWkList
          this.editForm.execDtList = data.data.execDtList
          this.editForm.tagStory = data.data.tagStory
          this.editForm.valueType = data.data.valueType
          this.editForm.rerun = !!data.data.rerun
          this.editForm.rerunTime = data.data.rerunTime || 1
          this.editForm.dataLabs = data.data.tagConfigJson.configJson
          this.editForm.results = data.data.previewResults
          this.preview = true
          if (data.data.tagConfigJson.catalogClassId)
            this.$parent.changeCatalogClass(data.data.tagConfigJson.catalogClassId)
        } else {
          this.$message.error(data.data || data.msg)
        }
      })
    },
    setGroup(groupId) {
      this.editForm.groupId = groupId
    },
    allowDrag(event) {
      event.preventDefault()
    },
    copyDrag(event, item, index) {
      event.dataTransfer.setData('drag_type', 'delete')
      event.dataTransfer.setData('index', index)
      event.dataTransfer.setData('type_id', item.type_id)
      if (item.type_id == '1') {
        event.dataTransfer.setData('tagId', item.tag_id)
        event.dataTransfer.setData('tagNm', item.tag_nm)
        event.dataTransfer.setData('labTbl', item.lab_table)
        event.dataTransfer.setData('labFldMap', item.lab_column)
        event.dataTransfer.setData('isDerLabel', item.isDerLabel)
      } else if (item.type_id == '2') {
        event.dataTransfer.setData('func_config', JSON.stringify(item))
      } else {
        event.dataTransfer.setData('operator', item.symbol)
        event.dataTransfer.setData('showOperator', item.showOperator)
      }
    },
    copyDrop(event) {
      let target = event.target
      const type_id = event.dataTransfer.getData('type_id')
      const drag_type = event.dataTransfer.getData('drag_type')
      const tagId = event.dataTransfer.getData('tagId')
      let isDelete = target.className && target.className.includes('delete-area')
      if (drag_type === 'delete' && isDelete) {
        const index = event.dataTransfer.getData('index')
        this.editForm.dataLabs.splice(index, 1)
      } else {
        const oldIndex = event.dataTransfer.getData('index')
        let nodes = []
        let index = -1
        while (target.className !== 'calculate-canvas') {
          nodes.push(target)
          if (target.className && target.className.includes('data-item')) {
            index = parseInt(target.getAttribute('index'))
          }
          target = target.parentNode
        }
        if (drag_type === 'delete') {
          if (index < 0) return
          // 先把旧数据删掉
          this.editForm.dataLabs.splice(oldIndex, 1)
          if (index > oldIndex) index--
        }
        if (tagId && nodes.find(nodeTarget => nodeTarget.className && nodeTarget.className.includes('func-tag'))) {
          // 将标签拖入到函数里面
          const func_tag = nodes.find(nodeTarget => nodeTarget.className.includes('func-tag'))
          const func_index = parseInt(func_tag.getAttribute('index'))
          const tagNm = event.dataTransfer.getData('tagNm')
          const labTbl = event.dataTransfer.getData('labTbl')
          const labFldMap = event.dataTransfer.getData('labFldMap')
          const isDerLabel = event.dataTransfer.getData('isDerLabel')
          this.editForm.dataLabs[index].func_param.param[func_index].param.tag_nm = tagNm
          this.editForm.dataLabs[index].func_param.param[func_index].param.lab_table = labTbl
          this.editForm.dataLabs[index].func_param.param[func_index].param.lab_column = labFldMap
          this.editForm.dataLabs[index].func_param.param[func_index].param.isDerLabel = isDerLabel
        } else {
          if (tagId) {
            // 拖入标签
            const tagNm = event.dataTransfer.getData('tagNm')
            const labTbl = event.dataTransfer.getData('labTbl')
            const labFldMap = event.dataTransfer.getData('labFldMap')
            const isDerLabel = event.dataTransfer.getData('isDerLabel')
            this.addItem({ tagId, tagNm, labTbl, labFldMap, isDerLabel, type_id: type_id || '1' }, index)
          } else {
            if (type_id == '2') {
              // 函数
              const func_config = JSON.parse(event.dataTransfer.getData('func_config'))
              this.addItem({ type_id, ...func_config }, index)
            } else {
              // 公式
              const operator = event.dataTransfer.getData('operator')
              const showOperator = event.dataTransfer.getData('showOperator')
              this.addItem({ operator, showOperator, type_id: type_id }, index)
            }
          }
        }
      }
    },
    addItem(item, index = -1) {
      let params = {}
      if (item.type_id == '1') {
        // 标签
        params = {
          type_id: item.type_id,
          isDerLabel: item.isDerLabel,
          tag_id: item.tagId || item.assetId,
          tag_nm: item.tagNm || item.assetNm,
          lab_table: item.labTbl,
          lab_column: item.labFldMap,
          symbol: '',
          func_param: {}
        }
      } else if (item.type_id == '0') {
        // 符号
        params = {
          type_id: item.type_id,
          symbol: item.operator,
          showOperator: item.showOperator,
          tag_nm: '',
          lab_table: '',
          lab_column: '',
          func_param: {}
        }
      } else if (item.type_id == '2') {
        params = {
          type_id: item.type_id,
          symbol: '',
          lab_table: '',
          lab_column: '',
          func_param: {
            func_id: item.funcId || item.func_param.func_id,
            func_name: item.funcIdentifier || item.func_param.func_name,
            param: []
          }
        }
        const selectList = item.funcParam || item.func_param.param
        selectList.forEach(func => {
          params.func_param.param.push({
            type_id: func.type_id,
            param: {
              tag_nm: '',
              isDerLabel: func.isDerLabel,
              lab_table: '',
              lab_column: '',
              constant: '',
              company: '',
              show_company: '',
              company_list: func.identifier_name || func.param.company_list
            }
          })
        })
      }
      if (index < 0 || index >= this.editForm.dataLabs.length) this.editForm.dataLabs.push(params)
      else this.editForm.dataLabs.splice(index + 1, 0, params)
    },
    handleDelete() {
      if (this.editForm.dataLabs.length) this.deleteItem(this.editForm.dataLabs.length - 1)
    },
    deleteItem(index) {
      this.editForm.dataLabs.splice(index, 1)
    },
    handlePreview() {
      if (!this.editForm.dataLabs.length) {
        this.$message.info('请添加计算公式！')
        return
      }
      this.$refs.editForm.validate(valid => {
        if (valid) {
          this.loading = true
          const dataLabs = {
            configJson: this.editForm.dataLabs,
            catalogClassId: this.$parent.getCatalogClass()
          }
          this.$ajax({
            url: this.$ajax.setUrl('der/derTagCalculation/show'),
            method: 'post',
            data: this.$ajax.setData({
              labs: JSON.stringify(dataLabs)
            })
          }).then(({ data }) => {
            if (data && data.code === '0') {
              this.preview = true
              this.editForm.results = data.data
              this.previewLabs = cloneDeep(this.editForm.dataLabs)
              this.$message.success(data.msg)
            } else {
              this.$message.error(data.data || data.msg)
            }
            this.loading = false
          })
        }
      })
    },
    handleSave() {
      if (!this.editForm.dataLabs.length) {
        this.$message.info('请添加计算公式！')
        return
      }
      let previewLabs = cloneDeep(this.previewLabs)
      if (!this.$utils.compareArray(this.editForm.dataLabs, previewLabs)) {
        this.$message.info('运算公式有变化，请先预览再保存！')
        return
      }
      const dataLabs = {
        configJson: this.editForm.dataLabs,
        catalogClassId: this.$parent.getCatalogClass()
      }
      const params = {
        groupId: this.editForm.groupId,
        tagId: this.editForm.tagId,
        tagNm: this.editForm.tagNm,
        fieldNm: this.editForm.fieldNm,
        execFrequency: this.editForm.execFrequency,
        execTm: this.editForm.execTm,
        execWkList: this.editForm.execWkList,
        execDtList: this.editForm.execDtList,
        tagStory: this.editForm.tagStory,
        valueType: this.editForm.valueType,
        rerun: this.editForm.rerun,
        rerunTime: this.editForm.rerunTime,
        dataLabs: JSON.stringify(dataLabs),
        results: JSON.stringify(this.editForm.results)
      }
      if (!this.preview)
        this.$refs.editForm.validate(valid => {
          if (valid) {
            this.$refs.calculateDrawer.showDrawer(params)
          }
        })
      else this.$refs.calculateDrawer.showDrawer(params)
    },
    confirm(params) {
      this.editForm.tagId = params.tagId
      this.editForm.tagNm = params.tagNm
      this.editForm.fieldNm = params.fieldNm
      this.editForm.execFrequency = params.execFrequency
      this.editForm.execTm = params.execTm
      this.editForm.execWkList = params.execWkList
      this.editForm.execDtList = params.execDtList
      this.editForm.tagStory = params.tagStory
      this.editForm.valueType = params.valueType
      this.editForm.rerun = params.rerun
      this.editForm.rerunTime = params.rerunTime
      let config = cloneDeep(this.oldConfig)
      this.oldConfig = Object.assign({}, config, { tagConfigJson: this.editForm.dataLabs }, params)
    },
    handleReject() {
      this.$confirm('确定取消最新的编辑？').then(() => {
        if (this.editForm.tagId) {
          const config = cloneDeep(this.oldConfig)
          this.editForm.tagNm = config.tagNm
          this.editForm.tagStory = config.tagStory
          this.editForm.valueType = config.valueType
          this.editForm.rerun = config.rerun
          this.editForm.rerunTime = config.rerunTime
          this.editForm.dataLabs = config.tagConfigJson
          this.editForm.results = config.previewResults
        } else {
          this.editForm.tagNm = ''
          this.editForm.tagStory = ''
          this.editForm.valueType = ''
          this.editForm.rerun = false
          this.editForm.rerunTime = 1
          this.editForm.dataLabs = []
          this.editForm.results = []
        }
        this.$forceUpdate()
      })
    },
    clearConfig() {
      this.editForm.rerun = false
      this.editForm.rerunTime = 1
      this.editForm.dataLabs = []
      this.editForm.results = []
      this.preview = false
    }
  }
}
</script>

<style lang="scss">
.factory-content {
  .calculate-content .calculate-canvas .config-tips {
    width: 400px;
    height: 300px;
    color: #999;
    text-align: center;
    position: absolute;
    top: calc(50% - 50px);
    left: 50%;
    transform: translate(-50%, -50%);
    span {
      display: inline-block;
      width: 30px;
      height: 30px;
      line-height: 30px;
      border: 2px solid #999;
      text-align: center;
      margin-right: 10px;
      border-radius: 5px;
      margin: 100px 0 20px 0;
      i {
        font-size: 20px;
        font-weight: bold;
      }
    }
  }
}
</style>
